package com.liting.uitest.imgutils;


import org.opencv.core.*;
import org.opencv.core.Core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 信息量
 */
public class ImageEntropy {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static double calculateEntropy1(BufferedImage image) {
        int[] histogram = new int[256];
        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                int pixel = image.getRGB(x, y);
                int gray = (pixel & 0xFF); // 提取灰度值
                histogram[gray]++;
            }
        }

        double entropy = 0.0;
        double probability;
        for (int i = 0; i < 256; i++) {
            if (histogram[i] > 0) {
                probability = histogram[i] / (double) (image.getWidth() * image.getHeight());
                entropy -= probability * Math.log(probability) / Math.log(2);
            }
        }
        return entropy;
    }

    public static double calculateEntropy(String imagFile) {
        // 读取图像
        Mat image = Imgcodecs.imread(imagFile);
        // 将图像转换为灰度图像
        Mat grayImage = new Mat();
        Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY);

        // 获取图像的宽度和高度
        int width = grayImage.cols();
        int height = grayImage.rows();

        // 初始化灰度级频率数组
        int[] histogram = new int[256];
        Arrays.fill(histogram, 0);

        // 统计每个灰度级的频率
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                double pixelValue = (double) grayImage.get(i, j)[0]; // OpenCV中灰度图像每个像素是一个数值
                histogram[(int) pixelValue]++;
            }
        }

        // 计算总像素数
        int totalPixels = width * height;

        // 计算概率分布
        double[] probabilities = new double[256];
        for (int i = 0; i < 256; i++) {
            probabilities[i] = (double) histogram[i] / totalPixels;
            // 防止概率为0导致log运算错误
            probabilities[i] = probabilities[i] > 0 ? probabilities[i] : Math.pow(2, -32); // 这里设定一个极小值避免分母为0
        }

        // 计算熵
        double entropy = 0.0;
        for (double p : probabilities) {
            entropy -= p * Math.log(p) / Math.log(2);
        }

        return entropy;
    }

    public static void main(String[] args) throws Exception {
        double entropy = calculateEntropy("C:\\Users\\lit21245\\Pictures\\Buy.jpg");


//
//        BufferedImage image2 = ImageIO.read(new File("C:\\Users\\lit21245\\Pictures\\1111.jpg")); // 替换为你的图像路径
//        double entropy2 = calculateEntropy1(image2);
//        System.out.println("Image Entropy: " + entropy2);

        System.out.println("Entropy: " + entropy);

        BufferedImage image = ImageIO.read(new File("C:\\Users\\lit21245\\Pictures\\Buy.jpg")); // 替换为你的图像路径
        double entropy2 = calculateEntropy1(image);
        System.out.println("Image Entropy: " + entropy2);
    }

}
